#include <stdarg.h>
#include <string.h>
#include <assert.h>
#include "redispool.h"
#include "sys_util.h"

REDISPOOL* pREdisPool;

int GetRedisServer()
{
	return (random()%(server_cfg.REDIS_SERVER_NUM));
}

int InitRedisPool()
{
	pREdisPool = (REDISPOOL*)malloc(sizeof(REDISPOOL)* server_cfg.REDIS_POOL_SIZE);

	struct timeval tv = {1, 0};
	
	int i = 0;
	while(i < server_cfg.REDIS_POOL_SIZE)
	{
		int iSer = GetRedisServer();
		strcpy(pREdisPool[i].ip, server_cfg.redis_cfg[iSer].REDIS_SERVER_HOST);
		pREdisPool[i].port = server_cfg.redis_cfg[iSer].REDIS_SERVER_PORT;

		pREdisPool[i].pConn = redisConnectWithTimeout(pREdisPool[i].ip, pREdisPool[i].port, tv);
		if(pREdisPool[i].pConn->err){
			redisFree(pREdisPool[i].pConn);
			printf("REDIS:  process[%d], redisserver[%s], LINK[%d]: connection create failure \n",  getpid(), pREdisPool[i].ip, i);
			memset(pREdisPool + i, 0x00, sizeof(REDISPOOL));
			return -1;
		}else{
			pREdisPool[i].flag = 0;
			pREdisPool[i].create_at = time(NULL);
			printf("REDIS:  process[%d], redisserver[%s], LINK[%d]: connection created \n",  getpid(), pREdisPool[i].ip, i);
		}

		i++;
	}
	
	return 0;
}


int FreeRedisPool()
{
	int i = 0;
	while(i < server_cfg.REDIS_POOL_SIZE)
	{
		redisFree(pREdisPool[i].pConn);
		memset(pREdisPool + i, 0x00, sizeof(REDISPOOL));
		i++;
	}
}

int CheckRedisPool()
{
	int i = 0;
	while(i < server_cfg.REDIS_POOL_SIZE)
	{
		if(pREdisPool[i].flag == -1)
		{	
			printf("REDIS:  process[%d], redisserver[%s], LINK[%d]: connection closed \n",  getpid(), pREdisPool[i].ip, i);
			redisFree(pREdisPool[i].pConn);
			memset(pREdisPool + i, 0x00, sizeof(REDISPOOL));

			int iSer = GetRedisServer();
			struct timeval tv = {1, 0};
			strcpy(pREdisPool[i].ip, server_cfg.redis_cfg[iSer].REDIS_SERVER_HOST);
			pREdisPool[i].port = server_cfg.redis_cfg[iSer].REDIS_SERVER_PORT;

			pREdisPool[i].pConn = redisConnectWithTimeout(pREdisPool[i].ip, pREdisPool[i].port, tv);
			if(pREdisPool[i].pConn->err){
				redisFree(pREdisPool[i].pConn);
				printf("REDIS:  process[%d], redisserver[%s], LINK[%d]: connection create failure \n",  getpid(), pREdisPool[i].ip, i);
				memset(pREdisPool + i, 0x00, sizeof(REDISPOOL));
				return -1;
			}else{
				pREdisPool[i].flag = 0;
				pREdisPool[i].create_at = time(NULL);
				printf("REDIS:  process[%d], redisserver[%s], LINK[%d]: connection created \n",  getpid(), pREdisPool[i].ip, i);
			}
		}

		i++;
	}
	
	return 0;
}

int GetRedisConn()
{
	int i = 0;
	while(i < server_cfg.REDIS_POOL_SIZE)
	{
		if(pREdisPool[i].flag == 0){
			return i;
		}else{
			i++;
		}
	}

	printf("REDIS: process[%d]: need more connection \n", getpid());
	return -1;
}

int PushRedisList(const char * pBuf)
{
	if(pBuf == NULL){
		return -1;
	}

	int i = GetRedisConn();
	if (i == -1) {
		return -1;
	}

//	redisReply* r = (redisReply*)redisCommand(pREdisPool[i].pConn, "lpush wait_list \"\%s\"", pBuf);
	redisReply* r = (redisReply*)redisCommand(pREdisPool[i].pConn, "RPUSH wait_list %s", pBuf);
	if (NULL == r) {
		pREdisPool[i].flag = -1;
	}

	if(r->type == REDIS_REPLY_INTEGER){
		printf("REDIS:  process[%d], redisserver[%s], LINK[%d]: Succeed to execute lpush wait_list [%s].\n", getpid(), pREdisPool[i].ip, i, pBuf);
		freeReplyObject(r);
		return 0;
	}else{
		printf("REDIS:  process[%d], redisserver[%s], LINK[%d]: FAILED to execute lpush wait_list [%s].\n", getpid(), pREdisPool[i].ip, i, pBuf);
		freeReplyObject(r);
		return -1;
	}
}

int PopRedisList(const char * pBuf)
{
	if(pBuf == NULL){
		return -1;
	}

	int i = GetRedisConn();
	if (i == -1) {
		return -1;
	}

	redisReply* r = (redisReply*)redisCommand(pREdisPool[i].pConn, "LPOP already_list");
	if (NULL == r) {
		pREdisPool[i].flag = -1;
	}

	if(r->type == REDIS_REPLY_STRING){
		strcpy(pBuf, r->str);
		printf("REDIS:  process[%d], redisserver[%s], LINK[%d]: Succeed to execute lpop already_list [%s].\n", getpid(), pREdisPool[i].ip, i, pBuf);
		freeReplyObject(r);
		return 0;
	}else{
		printf("REDIS:  process[%d], redisserver[%s], LINK[%d]: FAILED to execute lpop already_list.\n", getpid(), pREdisPool[i].ip, i);
		freeReplyObject(r);
		return -1;
	}
}
